﻿#region using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;
using System.Data;
using System.Text;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Threading;
using System.Globalization;
using Microsoft.Win32;
using System.Net.Mail;
using System.Data.Sql;
using System.Diagnostics;
#endregion
namespace Turtle8
{

    public class CompanyManager
    {
        #region definitions
        private static CompanyManager instance = new CompanyManager();
        private static Regex regEx = new Regex("[^0-9a-zA-z]");
        internal SqlManager sqlManager;
        private static Dictionary<string, string> dict;//holds the  mapping between the engWord to hebWord
        public static readonly string StartupPath = System.IO.Directory.GetCurrentDirectory();
        
        #endregion

        #region Constructors
        private CompanyManager()
        {
            validateSingletonProcess();
            if (getValueFromInitFile("IsInitialized").Equals("false"))
                new Initialization(sqlManager);
            sqlManager = new SqlManager();
            
            createEnglishHebrewDictionaryListFromDatabase();
            createEnglishHebrewListFromFile();
        }
        #endregion

        //Singleton
        public static CompanyManager getInstance() { return instance; }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainMenuGUI());
        }

        #region static methods

        /// <summary>
        /// a parser for company.ini initialization file.
        /// </summary>
        /// <param name="key"></param>
        /// <returns>the right value of the key
        ///          example: IsInitialized=false. the function retrurns "false";
        /// </returns>
        static internal string getValueFromInitFile(string key)
        {
            // create reader & open file
            TextReader tr = new StreamReader(@"other\company.ini");
            string line;
            string value = string.Empty;

            while ((line = tr.ReadLine()) != null)
                if (line.StartsWith("<" + key))
                {
                    line = line.Substring(line.IndexOf("=") + 1);
                    value += line;

                    while ((!line.EndsWith(">") && (line = tr.ReadLine()) != null))
                        value += line;

                    value = value.Substring(0, value.Length - 1);
                    break;
                }

            tr.Close();
            return value.Trim();
        }

        static public bool deleteSoldier(string army_id)
        {
            string table_name = string.Empty;
            string allTablesCmd = @"SELECT * FROM INFORMATION_SCHEMA.TABLES";

            //retrieve the meta data of the tabels in this connection DataBase.
            SqlCommand deleteSqlCmd = SqlManager.SqlCommandFactory(string.Empty);
            SqlCommand tablesSqlCmd = SqlManager.SqlCommandFactory(allTablesCmd);

            //defining parameter and setting its values
            DataTable dt = SqlManager.selectSqlQueryDataTable(tablesSqlCmd);
            SqlParameter param = new SqlParameter("@armyID", army_id);
            deleteSqlCmd.Parameters.Add(param);

            //deleting the associated 'armyId' from all tables in database
            foreach (DataRow row in dt.Rows)
            {
                try
                {
                    // get the data
                    table_name = (string)row["TABLE_NAME"];
                    deleteSqlCmd.CommandText = @"DELETE FROM " + table_name + " WHERE armyID = @armyID";
                    SqlManager.executeNonQuery(deleteSqlCmd);

                }
                catch (Exception e)
                {
                    if (!(e.Message.StartsWith("Invalid column name")))
                        MessageBox.Show(e.Message);
                }
            }

            return true;
        }

        /// <summary>
        /// populates a table of israel cities at first initialization.
        /// </summary>
        static private void populateIsraelCitiesTable()
        {
            string sLine = String.Empty;
            string cmd = @"INSERT INTO IsraelCities (city) VALUES(@City);";

            FileStream fs = new FileStream(@"other\israel-cities.txt", FileMode.Open, FileAccess.Read);
            StreamReader sr = new StreamReader(fs, Encoding.GetEncoding("windows-1255"));

            SqlCommand sqlCmd = SqlManager.SqlCommandFactory(cmd);

            //inserting the cities into a DataBase
            while ((sLine = sr.ReadLine()) != null)
            {
                sqlCmd = SqlManager.SqlCommandFactory(cmd);
                sqlCmd.Parameters.Add("@City", SqlDbType.NVarChar).Value = sLine;
                SqlManager.executeNonQuery(sqlCmd);
            }

            // close the stream
            sr.Close();
        }

        static private void createEnglishHebrewDictionaryListFromDatabase()
        {
            dict = new Dictionary<string, string>();
            SqlCommand selectCmd = SqlManager.SqlCommandFactory(@"SELECT * FROM EnglishHebrewDictionary");

            selectCmd.Connection.Open();
            SqlDataReader reader = selectCmd.ExecuteReader();
            while (reader.Read())
                dict.Add((string)reader["engWord"], (string)reader["hebWord"]);

            selectCmd.Connection.Close();
        }


        /// <summary>
        /// receives an english word. 
        /// </summary>
        /// <param name="engWord"></param>
        /// <returns>the hebrew string as appears in the data base.</returns>
        static public string translateEnglishWord(string engWord)
        {
            if (engWord == string.Empty)
                return string.Empty;
            return dict[engWord];
        }

        /// <summary>
        /// receives an hebrew word.  
        /// </summary>
        /// <param name="hebWord"></param>
        /// <returns>the english string as appears in the data base.</returns>
        static public string translateHebrewWord(string hebWord)
        {
            Dictionary<string, string>.KeyCollection keys = dict.Keys;

            foreach (string key in keys)
                if (dict[key].Equals(hebWord))
                    return key;
            return string.Empty;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filename"></param>
        /// <returns>the filename as a string</returns>
        static public string getSqlStringFromFile(string filename)
        {
            TextReader tr = new StreamReader(Application.StartupPath + @"\sql" + filename,Encoding.GetEncoding("windows-1255"));

            // reads the whole file and returns it as a string.
            string str = tr.ReadToEnd();

            // close the stream.
            tr.Close();

            return str;
        }

        /// <summary>
        /// gets a collection of Columns. 
        /// sets it's HeaderText property to it's Hebrew display.
        /// </summary>
        /// <param name="collection"></param>
        public static void setTableColumnHeadersHebrew(DataGridViewColumnCollection collection)
        {
            Regex objNaturalPattern = new Regex("[0-9]");
            foreach (DataGridViewColumn item in collection)
            {
                item.HeaderText = objNaturalPattern.Replace(item.HeaderText, string.Empty);
                item.HeaderText = CompanyManager.translateEnglishWord(item.Name);
            }
        }

        public static void setTableColumnHeadersHebrew(DataColumnCollection collection)
        {
            Regex objNaturalPattern = new Regex("[0-9]");
            foreach (DataColumn item in collection)
            {
                item.ColumnName = objNaturalPattern.Replace(item.ColumnName, string.Empty);
                item.ColumnName = CompanyManager.translateEnglishWord(item.ColumnName);
            }
        }

        public static ICollection<string> parseSqlQueryParameters(string cmd)
        {
            ICollection<string> list = new List<string>();

            while (cmd.Contains('@'))
            {
                //truncating the unnecessary prefix of "@......."
                cmd = cmd.Substring(cmd.IndexOf('@') + 1);

                //finds the first occurence  of a non alphabetic symbol
                Match m = regEx.Match(cmd);
                int i = m.Index;
                if (i != 0)
                    list.Add(cmd.Substring(0, i).Trim());
                else list.Add(cmd.Trim());
            }
            return list;
        }


        static public byte[] imageToByteArray(System.Drawing.Image imageIn)
        {
            MemoryStream ms = new MemoryStream();
            imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);

            return ms.ToArray();
        }

        static public Image byteArrayToImage(byte[] byteArrayIn)
        {
            MemoryStream ms = new MemoryStream(byteArrayIn);
            Image returnImage = Image.FromStream(ms);
            return returnImage;
        }

        private void createEnglishHebrewListFromFile()
        {
            dict = new Dictionary<string, string>();

            string[] file = File.ReadAllLines(Application.StartupPath + @"\other\" + "engHebDict.txt");
            string[] parse = new string[2];


            foreach (string s in file)
            {
                parse = s.Split('=');
                dict.Add(parse[0], parse[1]);
            }
        }
        
       

        public static SqlParameter createSqlParameter(string paramName, SqlDbType sdt, DataRowVersion drVersion, string columnStr)
        {
            SqlParameter sqlParameter = new SqlParameter(paramName, sdt);
            sqlParameter.SourceVersion = drVersion;
            sqlParameter.SourceColumn = columnStr;

            return sqlParameter;
        }
        #endregion

        /// <summary>
        /// validates that only 1 process instance runs at a time on the same machine.
        /// </summary>
        private void validateSingletonProcess()
        {
            string currentName = Process.GetCurrentProcess().ProcessName;
            Process currentProcess = Process.GetCurrentProcess();
            Array arr = Process.GetProcesses();

            foreach (Process item in arr)
            {
                if (item.ProcessName.Equals(currentName) && !item.Id.Equals(currentProcess.Id))
                    currentProcess.Kill();
            }
            string processName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;

        }
    }
}
